package com.zhangxx.inventory.thread.threadpool;
import com.google.common.base.Joiner;
import com.zhangxx.inventory.pojo.ProductInventory;
import com.zhangxx.inventory.thread.request.ProductInventoryCacheRefreshRequest;
import com.zhangxx.inventory.thread.request.ProductInventoryDBUpdateRequest;
import com.zhangxx.inventory.thread.request.Request;
import com.zhangxx.inventory.thread.request.RequestQueue;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
/**
 * @Description :队列执行者
 * @Author : leizhang
 * @Date 14:03 2022/3/18
 **/
@Slf4j
public class RequestProcessThread implements Callable<Boolean> {
    private static final Joiner JOINER = Joiner.on("_").skipNulls();
    private ArrayBlockingQueue<Request> queue;
    public RequestProcessThread(ArrayBlockingQueue<Request> queue){
        this.queue = queue;
    }
    @Override
    public Boolean call() throws Exception {
        try{
            for(;;){
                //从队列消费Request
                Request request = queue.take();
                boolean forceRefresh = request.forceRefresh();
                //请求去重,是否强制刷新
                if (!forceRefresh) {
                    RequestQueue requestQueue = RequestQueue.getInstance();
                    //并发安全的map，数据格式{"warehouseCode_stockCode_productId":true/false},全局标识位
                    Map<String, Boolean> flagMap = requestQueue.getFlagMap();
                    ProductInventory productInfo = request.getProductInfo();
                    String key = JOINER.join(productInfo.getWarehousCode(),productInfo.getStockCode(),productInfo.getProductId());
                    if (request instanceof ProductInventoryDBUpdateRequest) {
                        //如果是一个更新请求，请求入队列，更新标识位，true，当前请求类型是更新请求
                        flagMap.put(key,true);
                    }else if (request instanceof ProductInventoryCacheRefreshRequest) {
                        Boolean flag = flagMap.get(key);
                        if (flag == null) {
                            //说明前置节点不存在 读取缓存或者更新的操作
                            flagMap.put(key,false);
                        }
                        if (flag != null && flag) {
                            //说明前置节点存在更新操作，可直接读取缓存
                            flagMap.put(key,false);
                        }
                        //前置节点存在更新请求，和读取缓存请求，直接过滤掉
                        if (flag != null && !flag) {
                            //刷新缓存
//                            return true;
                            continue;
                        }
                    }
                }
                //更新缓存，刷新redis
                request.process();
                /**
                 * @Description :
                 * 假如，执行完了一个读请求之后，假设数据已经刷新到redis中
                 * 但是可能存在redis的LRU算法会把redis中的数据清理掉，此时的flag ！= null and ！flase的
                 * 会直接执行第三种可能，return true  不会刷新缓存，此时缓存中依然没有当前productId对应的数据
                 * 此时标志位依然是false;
                 **/
            }
        }catch (Exception e){
            log.error(e.getMessage(),e);
        }
        return true;
    }
}
